


import { engine } from "../../engine/engine";
import { OperateName } from "./WebDBDefine";
import { WebTable } from "./WebTable";
import { WebTableOperator } from "./WebTableOperator";
import { WebValueData } from "./WebValueData";
import { WebWhereData } from "./WebWhereData";


export class WebStatement {

    tableName: string = '';


    whereData: WebWhereData;

    valueData: WebValueData;

    //操作方式
    operate: string = ''

    protected _operator: WebTableOperator;


    constructor(operator: WebTableOperator) {
        this._operator = operator;
    }

    run(...data: any): void {
        // console.log('run data is ', data.length)
        let table: WebTable = this._operator.getTable(this.tableName)
        if (table) {
            let ls = table.list;
            let temp = {}
            switch (this.operate) {
                case OperateName.update:
                    //支持？ 和 @ 
                    if (this.valueData.names.length == 0) {
                        //如果是问号形式，参数个数需要跟值和条件的个数相同
                        let needCount = this.whereData.keys.length + this.valueData.keys.length;
                        if (needCount != data.length) {
                            return;
                        }
                    }

                    for (let i = 0; i < ls.length; i++) {
                        const value = ls[i];
                        if (value == undefined) {
                            continue;
                        }
                        let flag = true;
                        if (!this.whereData.and) {
                            flag = false;
                        }
                        for (let index = 0; index < this.whereData.keys.length; index++) {
                            let key = this.whereData.keys[index];
                            let val = null;
                            if (this.valueData.names.length == 0) {
                                val = data[this.valueData.keys.length + index];
                            } else {
                                if (data.length > 0) {
                                    let d = data[0]
                                    val = d[this.whereData.names[index]];
                                }


                            }
                            // console.log(' val ', val, key)
                            if (val != undefined) {
                                flag = value[key] == val
                                if (this.whereData.and) {
                                    if (!flag) {
                                        break;
                                    }
                                } else {
                                    if (flag) {
                                        break;
                                    }
                                }
                            } else {
                                engine.error(' val is null ', key)
                            }


                        }
                        // console.log(' flag ', flag)
                        if (flag) {
                            if (this.valueData.names.length == 0) {//？形式
                                for (let index = 0; index < this.valueData.keys.length; index++) {
                                    const element = this.valueData.keys[index];
                                    value[element] = data[index]
                                }
                            } else {//@形式
                                if (data.length > 0) {
                                    let d = data[0]
                                    let error = table.checkData(d)
                                    if (!error) {
                                        for (let index = 0; index < this.valueData.keys.length; index++) {
                                            const element = this.valueData.keys[index];
                                            value[element] = d[this.valueData.names[index]]
                                        }
                                    } else {
                                        engine.error(error)
                                    }
                                    // console.log(' d ', d)

                                }

                            }

                            table.update()
                            // list.update(i, value)
                            break;
                        }
                    }
                    break;
                case OperateName.insert:
                    //支持问号？和艾特符@ 还没有做重复插入的处理TODO
                    temp = table.template;
                    for (let index = 0; index < this.valueData.keys.length; index++) {
                        const key = this.valueData.keys[index];

                        // console.log(' ', index, data[index], key, data[0])
                        let d = null;
                        if (this.whereData.keys.length > 0 && data[0]) {
                            let key = this.whereData.keys[index];
                            d = data[0][key]
                        } else {
                            d = data[index]
                        }
                        // console.log('inset d ', d)
                        if (d != undefined) {
                            if (table.isPrimary(key)) {
                                if (table.hasKey(key, d)) {
                                    engine.warn(' has key ', key, d)
                                    return;
                                }
                            }
                            temp[key] = d;
                        } else {
                            engine.error(' missing key ', key)
                        }
                    }
                    ls.push(temp)
                    // console.log('insert  temp ', temp)
                    table.update()
                    break;
                case OperateName.delete:
                    if (this.whereData.names.length == 0) {
                        if (this.whereData.keys.length != data.length) {
                            return;
                        }
                    }

                    for (let i = 0; i < ls.length; i++) {
                        const value = ls[i];
                        if (value == undefined) {
                            continue;
                        }
                        let flag = true;
                        if (!this.whereData.and) {
                            flag = false;
                        }
                        for (let index = 0; index < this.whereData.keys.length; index++) {
                            let key = this.whereData.keys[index];
                            let d = null;
                            if (this.whereData.names.length > 0 && data[0]) {
                                let key = this.whereData.names[index];
                                d = data[0][key]
                            } else {
                                d = data[index]
                            }
                            if (d != undefined) {
                                flag = value[key] == d
                                if (this.whereData.and) {
                                    if (!flag) {
                                        break;
                                    }
                                } else {
                                    if (flag) {
                                        break;
                                    }
                                }
                            } else {
                                engine.error(' missing key ', key)
                            }

                        }
                        if (flag) {
                            ls.splice(i, 1)
                            table.update()
                            break;
                        }
                    }

                    break;
            }
        } else {
            engine.warn(' not have table ', this.tableName)
        }

    }

    private isAll() {
        return this.valueData.keys.length == 1 && this.valueData.keys[0] == '*'
    }
    /**
     * 返回值需要跟sqlite3兼容
     * @param data 
     * @returns 
     */
    get(...data: any): any {
        if (this.valueData.keys.length == 0) {
            return null;
        }
        if (this.isAll()) {
            return this.all(...data)
        }
        let table: WebTable = this._operator.getTable(this.tableName)
        if (table) {
            let ls = JSON.parse(JSON.stringify(table.list));//深拷贝
            // console.log(' ls ', ls)
            if (this.operate == OperateName.select) {
                if (this.valueData.names.length == 0) {
                    //如果是问号形式，参数个数需要跟值和条件的个数相同
                    if (this.whereData.keys.length != data.length) {
                        console.error('select  count error this.whereKeys.length ', this.whereData.keys.length, data.length)
                        return null;
                    }
                }
                for (let i = 0; i < ls.length; i++) {
                    const value = ls[i];
                    if (value == undefined) {
                        continue;
                    }
                    let flag = true;
                    if (!this.whereData.and) {
                        flag = false;
                    }
                    for (let index = 0; index < this.whereData.keys.length; index++) {
                        let key = this.whereData.keys[index];
                        let val = null;
                        if (this.valueData.names.length == 0) {
                            val = data[index];
                        } else {
                            if (data.length > 0) {
                                let d = data[0]
                                val = d[this.whereData.names[index]];
                            }

                        }
                        if (val != undefined) {
                            flag = value[key] == val
                            // console.log(' value[key] == data[index] ', value[key], key, data[index])
                            if (this.whereData.and) {
                                if (!flag) {
                                    break;
                                }
                            } else {
                                if (flag) {
                                    break;
                                }
                            }
                        }

                    }
                    if (flag) {
                        let obj = {}
                        for (let index = 0; index < this.valueData.keys.length; index++) {
                            const element = this.valueData.keys[index];
                            obj[element] = value[element]
                        }
                        return obj;
                    }
                }
            } else {
                console.warn('table is null ', this.tableName)
            }
        }
        return null;
    }


    all(...data: any): any[] {
        if (this.valueData.keys.length == 0) {
            return [];
        }
        if (!this.isAll()) {
            return null
        }
        let table: WebTable = this._operator.getTable(this.tableName)
        if (table) {
            let ls = JSON.parse(JSON.stringify(table.list));//深拷贝
            if (this.operate == OperateName.select) {
                let temp = []
                if (this.whereData.keys.length > 0) {
                    if (this.whereData.data.length == 0 && this.valueData.names.length == 0) {
                        //如果是问号形式，参数个数需要跟值和条件的个数相同
                        if (this.whereData.keys.length != data.length) {
                            console.error('select  count error this.whereKeys.length ', this.whereData.keys.length, data.length)
                            return null;
                        }
                    }
                    for (let i = 0; i < ls.length; i++) {
                        const value = ls[i];
                        if (value == undefined) {
                            continue;
                        }
                        let flag = true;
                        if (!this.whereData.and) {
                            flag = false;
                        }
                        for (let index = 0; index < this.whereData.keys.length; index++) {
                            let key = this.whereData.keys[index];
                            let val = null;
                            if (this.valueData.names.length == 0) {
                                if (this.whereData.data.length > 0) {
                                    val = this.whereData.data[index];
                                } else {
                                    val = data[index];
                                }
                            } else {
                                if (data.length > 0) {
                                    let d = data[0]
                                    val = d[this.whereData.names[index]];
                                }
                            }
                            if (val != undefined) {
                                flag = value[key] == val
                                if (this.whereData.and) {
                                    if (!flag) {
                                        break;
                                    }
                                } else {
                                    if (flag) {
                                        break;
                                    }
                                }
                            }

                        }
                        if (flag) {
                            temp.push(value)
                        }
                    }

                } else {
                    for (let i = 0; i < ls.length; i++) {
                        const value = ls[i];
                        if (value == undefined) {
                            continue;
                        }
                        temp.push(value)
                    }
                }
                return temp;
            }


        } else {
            console.warn('table is null ', this.tableName)
        }
        return [];
    }
}